package com.xixibaby.core.service;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.xixibaby.core.*;
import com.xixibaby.core.Optionals;
import com.xixibaby.core.Assert;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.function.Function;


/**
 * @author tomj
 */
@Slf4j
public abstract class DBServiceImpl<
        MAPPER extends SuperMapper<PO>,
        PO extends SuperPO,
        RESPONSE extends SuperResponse,
        REQUEST extends SuperRequest,
        CONCATER extends SuperConverter<PO,RESPONSE,REQUEST>>
        extends SuperServiceImpl<MAPPER,PO,RESPONSE,REQUEST,CONCATER>{

    @Autowired
    protected MAPPER mapper;

    /**
     * 组装查询wrapper
     * @param vo
     * @return
     */
    @Override
    public Wrapper<PO> getQueryWrapper(REQUEST vo){
        PO po = concater.toPO(vo);
        return getEmptyWrapper().setEntity(po);
    }


    protected LambdaQueryWrapper<PO> getEmptyWrapper(){
        return Wrappers.<PO>query().lambda();
    }



    @Override
    protected List<PO> listDb(REQUEST vo) {
        return list(getQueryWrapper(vo));
    }



    @Override
    protected IPage<PO> pageListDb(REQUEST request) {
        return  pageListDb(request,this::getQueryWrapper);
    }

    @Override
    protected IPage<PO> pageListDb(REQUEST request, Function<REQUEST, Wrapper<PO>> function) {
        IPage<PO> page = getPage(request);
        return page(page, function.apply(request));
    }

    @Override
    protected PO selectByIdDb(REQUEST vo) {
        return this.mapper.selectById(vo.getId());
    }

    @Override
    protected PO insertDb(REQUEST vo) {
        PO po = concater.toPO(vo);
        Assert.succ(save(po)).thenThrow("新增失败！");
        return po;
    }



    @Override
    protected PO updateDb(REQUEST vo) {
        PO po = concater.toPO(vo);
        Assert.succ(super.updateById(po)).thenThrow("数据修改失败！可能是版本号已经过期！");
        return this.getById(vo.getId());
    }

    @Override
    protected PO deleteDb(REQUEST vo) {
        PO byId = getById(vo.getId());
        Assert.succ(super.removeById(vo.getId())).thenThrow("删除失败！");
        return byId;
    }

    @Override
    protected PO selectCacheById(REQUEST vo) {
        return null;
    }

    @Override
    protected void insertCache(PO vo) {

    }

    @Override
    protected void updateCache(PO vo) {

    }

    @Override
    protected void deleteCache(PO vo) {

    }

    @Override
    public RESPONSE getLastInfo(PO entity) {
        return concater.toResult(entity);
    }


    public UpdateWrapper<PO> getDeleteWrapper(REQUEST request) {
        UpdateWrapper<PO> wrapper=new UpdateWrapper<>();
        Wrappers.update().eq("id",request.getId())
                .eq("version",request.getVersion())
                .set("deleted",1);
        return wrapper;
    }

    public IPage<PO> getPage(REQUEST request) {
        Integer size =  Optionals.of(request.getSize()).orElse(10);
        Integer curr =  Optionals.of(request.getCurrent()).orElse(1);
        return new Page<>(curr,size);
    }
}
